package client_gui;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

import parameters.RLM_DefaultParameterValues;
import parameters.RLM_Parameters;
import upnp.UPnpManager;
import utils.MessageViewer;
import utils.NICInfo;
import utils.NICManagerRLM;
import utils.PortScanner;
import client.RLMAutostart;

public class OptionsDialog extends JDialog {
	
	/**
	 * Parent - prozor aplikacije.
	 */
	private ClientWindow owner;
	
	
	private JPanel jContentPane = null;
	
	
	private JPanel serverPanel = null;
	private JPanel clientPanel = null;
	private JPanel buttonPanel = null;
	private JPanel nicPanel = null;

	private GridBagLayout serverGridBag = null;
	private GridBagLayout clientGridBag = null;
	private FlowLayout buttonFlow = null;
	private GridBagLayout nicPanelGridBag = null;
	
	
	private JButton okButton = null;
	private JButton cancelButton = null;
	
	
	private JLabel serverNameLabel = null;
	private JTextField serverNameField = null;
	private JLabel serverPortLabel = null;
	private JTextField serverPortField = null;
	
	private JLabel folderLabel = null;
	private JTextField folderField = null;
	private JButton browseButton = null;
	
	private JLabel tcpPortLabel = null;
	private JTextField tcpPortField = null;
	private JLabel audioPortLabel = null;
	private JTextField audioPortField = null;
	private JLabel videoPortLabel = null;
	private JTextField videoPortField = null;
	
	private JLabel nicLabel;
	private JLabel addressLabel;
	private JLabel loopbackLabel = new JLabel("");
	private JComboBox nicComboBox = null;
	private JComboBox addressComboBox = null;
	
	private JLabel lanLabel = null;
	private JCheckBox lanCheckBox = null;
	
	private GridBagConstraints serverNameLabelConstraint = null;
	private GridBagConstraints serverNameFieldConstraint = null;
	private GridBagConstraints serverPortLabelConstraint = null;
	private GridBagConstraints serverPortFieldConstraint = null;
	private GridBagConstraints folderLabelConstraint = null;
	private GridBagConstraints folderFieldConstraint = null;
	private GridBagConstraints browseButtonConstraint = null;
	private GridBagConstraints nicLabelConstraint = null;
	private GridBagConstraints addressLabelConstraint = null;
	private GridBagConstraints nicComboConstraint = null;
	private GridBagConstraints addressComboConstraint = null;
	private GridBagConstraints loopbackLabelConstraint = null;
	private GridBagConstraints autoStartLabelConstraint = null;
	private GridBagConstraints autoStartCheckBoxConstraint = null;
	private GridBagConstraints tcpPortFieldConstraint = null;
	private GridBagConstraints tcpPortLabelConstraint = null;
	private GridBagConstraints audioPortFieldConstraint = null;
	private GridBagConstraints audioPortLabelConstraint = null;
	private GridBagConstraints videoPortFieldConstraint = null;
	private GridBagConstraints videoPortLabelConstraint = null;
	private GridBagConstraints lanLabelConstraint = null;
	private GridBagConstraints lanCheckBoxConstraint = null;
	
	
	private boolean isLoopbackAdapter = false;
	private String nicToConnect = "";
	
	private static final String loopbackMessage = "Loopback adapter selected !\nRLM cannot start properly with this kind of adapter. Please, try another one!";
	
	
	private JLabel autoStartLabel = null;
	private JCheckBox autoStartCheckBox = null;
	
	
	/**
	 * Konstruktor.
	 * @param parent - prozor aplikacije
	 * @author UrosKrkic & Radivoje Popovic & Martin Jondzic
	 */
	public OptionsDialog(ClientWindow parent) {
		super(parent, "Options", true);
		
		this.owner = parent;
		
		initializeLayoutManagers();
		
		createConstraints();
		
		initializeConstraints();
		
		initialize();
	}
	
	
	
	/**
	 * Metod vrsi inicijalizaciju dialoga.
	 * @author UrosKrkic & Radivoje Popovic & Martin Jondzic
	 */
	private void initialize() {
//		this.setSize(370, 520);
		this.setContentPane(getJContentPane());
		this.pack();
		this.setLocation(owner.getX() + owner.getWidth() / 2 - this.getWidth() / 2, owner.getY() + owner.getHeight() / 2 - this.getHeight() / 2);
		this.setResizable(false);
		
		this.setIconImage(owner.getIconImage());
	}
	
	
	private void initializeLayoutManagers() {
		serverGridBag = new GridBagLayout();
		clientGridBag = new GridBagLayout();
		buttonFlow = new FlowLayout(FlowLayout.CENTER);
		
		buttonFlow.setHgap(30);
		
		nicPanelGridBag = new GridBagLayout();
	}
	
	
	private void createConstraints() {
		serverNameLabelConstraint = new GridBagConstraints();
		serverNameFieldConstraint = new GridBagConstraints();
		serverPortLabelConstraint = new GridBagConstraints();
		serverPortFieldConstraint = new GridBagConstraints();
		folderLabelConstraint = new GridBagConstraints();
		folderFieldConstraint = new GridBagConstraints();
		browseButtonConstraint = new GridBagConstraints();
		tcpPortFieldConstraint = new GridBagConstraints();
		audioPortFieldConstraint = new GridBagConstraints();
		tcpPortLabelConstraint = new GridBagConstraints();
		audioPortLabelConstraint = new GridBagConstraints();
		videoPortLabelConstraint = new GridBagConstraints();
		videoPortFieldConstraint = new GridBagConstraints();
		
		nicLabelConstraint = new GridBagConstraints();
		addressLabelConstraint = new GridBagConstraints();
		nicComboConstraint = new GridBagConstraints();
		addressComboConstraint = new GridBagConstraints();
		loopbackLabelConstraint = new GridBagConstraints();
		
		autoStartLabelConstraint = new GridBagConstraints();
		autoStartCheckBoxConstraint = new GridBagConstraints();	
		
		lanLabelConstraint = new GridBagConstraints();
		lanCheckBoxConstraint = new GridBagConstraints();
	}
	
	
	private void initializeConstraints() {
		serverNameLabelConstraint.gridx = 0;
		serverNameLabelConstraint.gridy = 0;
		serverNameLabelConstraint.weightx = 1;
		serverNameLabelConstraint.weighty = 1;
		serverNameLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		serverNameLabelConstraint.insets = new Insets(10,5,5,0);
		
		serverNameFieldConstraint.gridx = 1;
		serverNameFieldConstraint.gridy = 0;
		serverNameFieldConstraint.weightx = 1;
		serverNameFieldConstraint.weighty = 1;
		serverNameFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		serverNameFieldConstraint.insets = new Insets(10,5,5,0);
		
		serverPortLabelConstraint.gridx = 0;
		serverPortLabelConstraint.gridy = 1;
		serverPortLabelConstraint.weightx = 1;
		serverPortLabelConstraint.weighty = 1;
		serverPortLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		serverPortLabelConstraint.insets = new Insets(0,5,5,0);
		
		serverPortFieldConstraint.gridx = 1;
		serverPortFieldConstraint.gridy = 1;
		serverPortFieldConstraint.weightx = 1;
		serverPortFieldConstraint.weighty = 1;
		serverPortFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		serverPortFieldConstraint.insets = new Insets(0,5,5,0);
		
		
		lanLabelConstraint.gridx = 0;
		lanLabelConstraint.gridy = 1;
		lanLabelConstraint.weightx = 1;
		lanLabelConstraint.weighty = 1;
		lanLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		lanLabelConstraint.insets = new Insets(0,5,5,0);
		
		lanCheckBoxConstraint.gridx = 1;
		lanCheckBoxConstraint.gridy = 1;
		lanCheckBoxConstraint.weightx = 1;
		lanCheckBoxConstraint.weighty = 1;
		lanCheckBoxConstraint.anchor = GridBagConstraints.NORTHWEST;
		lanCheckBoxConstraint.insets = new Insets(0,5,5,0);
		
		tcpPortLabelConstraint.gridx = 0;
		tcpPortLabelConstraint.gridy = 2;
		tcpPortLabelConstraint.weightx = 1;
		tcpPortLabelConstraint.weighty = 1;
		tcpPortLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		tcpPortLabelConstraint.insets = new Insets(10,5,5,0);
		
		tcpPortFieldConstraint.gridx = 1;
		tcpPortFieldConstraint.gridy = 2;
		tcpPortFieldConstraint.weightx = 1;
		tcpPortFieldConstraint.weighty = 1;
		tcpPortFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		tcpPortFieldConstraint.insets = new Insets(8,5,0,0);
		
		audioPortLabelConstraint.gridx = 0;
		audioPortLabelConstraint.gridy = 3;
		audioPortLabelConstraint.weightx = 1;
		audioPortLabelConstraint.weighty = 1;
		audioPortLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		audioPortLabelConstraint.insets = new Insets(11,5,5,0);
		
		audioPortFieldConstraint.gridx = 1;
		audioPortFieldConstraint.gridy = 3;
		audioPortFieldConstraint.weightx = 1;
		audioPortFieldConstraint.weighty = 1;
		audioPortFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		audioPortFieldConstraint.insets = new Insets(8,5,0,0);
		
		videoPortLabelConstraint.gridx = 0;
		videoPortLabelConstraint.gridy = 4;
		videoPortLabelConstraint.weightx = 1;
		videoPortLabelConstraint.weighty = 1;
		videoPortLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		videoPortLabelConstraint.insets = new Insets(11,5,5,0);
		
		videoPortFieldConstraint.gridx = 1;
		videoPortFieldConstraint.gridy = 4;
		videoPortFieldConstraint.weightx = 1;
		videoPortFieldConstraint.weighty = 1;
		videoPortFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		videoPortFieldConstraint.insets = new Insets(8,5,0,0);
		
		folderLabelConstraint.gridx = 0;
		folderLabelConstraint.gridy = 5;
		folderLabelConstraint.weightx = 1;
		folderLabelConstraint.weighty = 1;
		folderLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		folderLabelConstraint.insets = new Insets(13,5,5,0);
		
		folderFieldConstraint.gridx = 1;
		folderFieldConstraint.gridy = 5;
		folderFieldConstraint.weightx = 1;
		folderFieldConstraint.weighty = 1;
		folderFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		folderFieldConstraint.insets = new Insets(10,5,0,0);
		
		browseButtonConstraint.gridx = 1;
		browseButtonConstraint.gridy = 6;
		browseButtonConstraint.weightx = 1;
		browseButtonConstraint.weighty = 1;
		browseButtonConstraint.anchor = GridBagConstraints.NORTHWEST;
		browseButtonConstraint.insets = new Insets(0,5,5,0);
		
		autoStartLabelConstraint.gridx = 0;
		autoStartLabelConstraint.gridy = 7;
		autoStartLabelConstraint.weightx = 1;
		autoStartLabelConstraint.weighty = 1;
		autoStartLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		autoStartLabelConstraint.insets = new Insets(10,5,5,0);
		
		autoStartCheckBoxConstraint.gridx = 1;
		autoStartCheckBoxConstraint.gridy = 7;
		autoStartCheckBoxConstraint.weightx = 1;
		autoStartCheckBoxConstraint.weighty = 1;
		autoStartCheckBoxConstraint.anchor = GridBagConstraints.NORTHWEST;
		autoStartCheckBoxConstraint.insets = new Insets(8,0,5,0);
		
		nicLabelConstraint.gridx = 0;
		nicLabelConstraint.gridy = 0;
		nicLabelConstraint.weightx = 1;
		nicLabelConstraint.weighty = 1;
		nicLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		nicLabelConstraint.insets = new Insets(5,5,0,0);
		
		nicComboConstraint.gridx = 0;
		nicComboConstraint.gridy = 0;
		nicComboConstraint.weightx = 1;
		nicComboConstraint.weighty = 1;
		nicComboConstraint.anchor = GridBagConstraints.NORTHWEST;
		nicComboConstraint.insets = new Insets(25,5,5,0);
		
		addressLabelConstraint.gridx = 0;
		addressLabelConstraint.gridy = 1;
		addressLabelConstraint.weightx = 1;
		addressLabelConstraint.weighty = 1;
		addressLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		addressLabelConstraint.insets = new Insets(10,5,0,0);
		
		addressComboConstraint.gridx = 0;
		addressComboConstraint.gridy = 1;
		addressComboConstraint.weightx = 1;
		addressComboConstraint.weighty = 1;
		addressComboConstraint.anchor = GridBagConstraints.NORTHWEST;
		addressComboConstraint.insets = new Insets(5,100,5,0);
		
		loopbackLabelConstraint.gridx = 0;
		loopbackLabelConstraint.gridy = 1;
		loopbackLabelConstraint.weightx = 1;
		loopbackLabelConstraint.weighty = 1;
		loopbackLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		loopbackLabelConstraint.insets = new Insets(10,250,0,0);

	}

	
	
	
	// Metode koje inicijalizuju komponente dialoga.
	
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			
//			jContentPane.setLayout(new BorderLayout());

			GridBagLayout gb = new GridBagLayout();
			
			jContentPane.setLayout(gb);
			GridBagConstraints c0 = new GridBagConstraints();
			GridBagConstraints c1 = new GridBagConstraints();
			GridBagConstraints c2 = new GridBagConstraints();
			GridBagConstraints c3 = new GridBagConstraints();
			c0.gridx = 0;
			c0.gridy = 0;
			c0.weightx = 1;
			c0.weighty = 1;
			c0.fill = GridBagConstraints.HORIZONTAL;
			c0.anchor = GridBagConstraints.NORTHWEST;
			c0.insets = new Insets(5,5,5,5);
			
			c1.gridx = 0;
			c1.gridy = 1;
			c1.weightx = 1;
			c1.weighty = 1;
			c1.fill = GridBagConstraints.HORIZONTAL;
			c1.anchor = GridBagConstraints.NORTHWEST;
			c1.insets = new Insets(5,5,5,5);
			
			c2.gridx = 0;
			c2.gridy = 2;
			c2.weightx = 1;
			c2.weighty = 1;
			c2.fill = GridBagConstraints.HORIZONTAL;
			c2.anchor = GridBagConstraints.NORTHWEST;
			c2.insets = new Insets(5,5,5,5);
			
			c3.gridx = 0;
			c3.gridy = 3;
			c3.weightx = 1;
			c3.weighty = 1;
			c3.fill = GridBagConstraints.HORIZONTAL;
			c3.anchor = GridBagConstraints.NORTHWEST;
			c3.insets = new Insets(5,5,5,5);
			
			gb.setConstraints(getServerPanel(), c0);
			gb.setConstraints(getClientPanel(), c1);
			gb.setConstraints(getNicPanel(), c2);
			gb.setConstraints(getButtonPanel(), c3);
			
			jContentPane.add(getServerPanel());
			jContentPane.add(getClientPanel());
			jContentPane.add(getNicPanel());
			jContentPane.add(getButtonPanel());
		}
		
		return jContentPane;
	}

	
	
	private JPanel getServerPanel() {
		if (serverPanel == null) {
			serverPanel = new JPanel();
			
			serverPanel.setLayout(serverGridBag);
			
			TitledBorder titledBorder = BorderFactory.createTitledBorder(BorderFactory.
					createEtchedBorder(EtchedBorder.RAISED),
					"Server Setttings", javax.swing.border.TitledBorder.CENTER,
					javax.swing.border.TitledBorder.DEFAULT_POSITION,
					null, null);
			
			serverPanel.setBorder(titledBorder);
			
			serverPanel.add(getServerNameLabel());
			serverPanel.add(getServerNameField());
			serverPanel.add(getServerPortLabel());
			serverPanel.add(getServerPortField());
		}
		
		return serverPanel;
	}
	
	
	private JPanel getClientPanel() {
		if (clientPanel == null) {
			clientPanel = new JPanel();
			
			clientPanel.setLayout(clientGridBag);
			
			TitledBorder titledBorder = BorderFactory.createTitledBorder(BorderFactory.
					createEtchedBorder(EtchedBorder.RAISED),
					"Client Settings", javax.swing.border.TitledBorder.CENTER,
					javax.swing.border.TitledBorder.DEFAULT_POSITION,
					null, null);
			
			clientPanel.setBorder(titledBorder);
			
			clientPanel.add(getLanLabel());
			clientPanel.add(getLanCheckBox());
			clientPanel.add(getTcpPortLabel());
			clientPanel.add(getTcpPortField());
			clientPanel.add(getAudioPortLabel());
			clientPanel.add(getAudioPortField());
			clientPanel.add(getVideoPortLabel());
			clientPanel.add(getVideoPortField());
			clientPanel.add(getFolderLabel());
			clientPanel.add(getFolderField());
			clientPanel.add(getBrowseButton());
			clientPanel.add(getAutoStartLabel());
			clientPanel.add(getAutoStartCheckBox());
		}
		
		return clientPanel;
	}
	
	
	private JPanel getButtonPanel() {
		if (buttonPanel == null) {
			buttonPanel = new JPanel();
			buttonPanel.setLocation(5, 90);
			buttonPanel.setSize(300,70);
			buttonPanel.setLayout(buttonFlow);
			
			Border border = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
			buttonPanel.setBorder(border);
			
			buttonPanel.add(getOKButton());
			buttonPanel.add(getCancelButton());
		}
		
		return buttonPanel;
	}
	
	private JButton getOKButton() {
		if (okButton == null) {
			okButton = new JButton("OK");
			okButton.setToolTipText("OK");
			okButton.setPreferredSize(new Dimension(80, 25));
			
			okButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					
					OptionsDialog.this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
					
					if ( !changeMade() ) {
						if ( isAutoStartChanged() ) {
							if ( autoStartCheckBox.isSelected() ) {
								RLMAutostart.addToStartup();
							}
							else {
								RLMAutostart.removeFromStartup();
							}
						}
						OptionsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
						OptionsDialog.this.dispose();
	
						return;
					}
					
					if ( changePortMade() ) {
//						boolean portValidationValue = PortScanner.validationWithInfo(serverPortField, "Server Port");
//						if (portValidationValue == false) {
//							OptionsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
//							return;
//						}
						
						try {
							Integer.parseInt(serverPortField.getText());
						}
						catch (Exception ex) {
							MessageViewer.showError(OptionsDialog.this, "Port Number must be a number!");
							return;
						}
					}
					
					
					if ( changeTcpPortMade() ) {
						boolean portValidationValue = PortScanner.validationWithInfo(tcpPortField, "TCP Port");
						if (portValidationValue == false) {
							OptionsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
							return;
						}
						
						UPnpManager.removeTcpForward(RLM_Parameters.getTcpPort());
						RLM_Parameters.setTcpPort(Integer.parseInt(tcpPortField.getText()));
						UPnpManager.addTcpForward("RLM_Client_TCP", RLM_Parameters.getTcpPort(), RLM_Parameters.getTcpPort(), RLM_Parameters.getNetworkInterfaceToConnect());
					}
					
					if ( changeAudioPortMade() ) {
						boolean portValidationValue = PortScanner.validationWithInfo(audioPortField, "Audio Port");
						if (portValidationValue == false) {
							OptionsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
							return;
						}
						
						UPnpManager.removeUdpForward(RLM_Parameters.getAudioPort());
						RLM_Parameters.setAudioPort(Integer.parseInt(audioPortField.getText()));
						UPnpManager.addUdpForward("RLM_Client_Audio", RLM_Parameters.getAudioPort(), RLM_Parameters.getAudioPort(), RLM_Parameters.getNetworkInterfaceToConnect());
					}
					
					if ( changeVideoPortMade() ) {
						boolean portValidationValue = PortScanner.validationWithInfo(videoPortField, "Video Port");
						if (portValidationValue == false) {
							OptionsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
							return;
						}
						
						UPnpManager.removeUdpForward(RLM_Parameters.getVideoPort());
						RLM_Parameters.setVideoPort(Integer.parseInt(videoPortField.getText()));
						UPnpManager.addUdpForward("RLM_Client_Video", RLM_Parameters.getVideoPort(), RLM_Parameters.getVideoPort(), RLM_Parameters.getNetworkInterfaceToConnect());
					}
					
					if ( isAutoStartChanged() ) {
						if ( autoStartCheckBox.isSelected() ) {
							RLMAutostart.addToStartup();
						}
						else {
							RLMAutostart.removeFromStartup();
						}
					}
					
			
					if ( isLoopbackAdapter ) {
						JOptionPane.showMessageDialog(OptionsDialog.this, loopbackMessage, "Loopback Adapter Warning", JOptionPane.WARNING_MESSAGE);
						OptionsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
						return;
					}

					if ( changeNicToConnectMade() ) {
						UPnpManager.removeTcpForward(RLM_Parameters.getTcpPort());
						UPnpManager.removeUdpForward(RLM_Parameters.getAudioPort());
						RLM_Parameters.setNetworkInterfaceToConnect(nicToConnect);
						
						String nicToConnect = RLM_Parameters.getNetworkInterfaceToConnect();
						
						// zbog discavery timeout-a
						try {
							Thread.sleep(4000);
						} catch (InterruptedException ex) {
							ex.printStackTrace();
						}
						
						UPnpManager.addTcpForward("RLM_Client_TCP", RLM_Parameters.getTcpPort(), RLM_Parameters.getTcpPort(), nicToConnect);
						UPnpManager.addUdpForward("RLM_Client_Audio", RLM_Parameters.getAudioPort(), RLM_Parameters.getAudioPort(), nicToConnect);
						UPnpManager.addUdpForward("RLM_Client_Video", RLM_Parameters.getVideoPort(), RLM_Parameters.getVideoPort(), nicToConnect);
						
//						UPnpManager.addTcpAndUdpForward("RLM_Client", RLM_Parameters.getTcpPort(), RLM_Parameters.getTcpPort());
					}
					
					
					RLM_Parameters.setLan(lanCheckBox.isSelected());
					
					RLM_Parameters.setServerName(serverNameField.getText());
					RLM_Parameters.setServerPort(Integer.parseInt(serverPortField.getText()));
					RLM_Parameters.setReceivedFolder(folderField.getText());
					
					RLM_Parameters.setNetworkInterfaceToConnect(nicToConnect);
					
					if ( NICManagerRLM.getNICByAddress(nicToConnect) == null ) {
						RLM_Parameters.setMACAddress(RLM_DefaultParameterValues.MAC_ADDRESS);
					}
					else {
						RLM_Parameters.setMACAddress(NICManagerRLM.getNICByAddress(nicToConnect).getNicMACAddress());
					}
					
					
					RLM_Parameters.storeParameters();
					
					OptionsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
					
					OptionsDialog.this.dispose();
					
				}
			});
		}
		
		return okButton;
	}
	
	
	private boolean changeMade() {
		if (
			serverNameField.getText().equals(RLM_Parameters.getServerName()) &&
			serverPortField.getText().equals(Integer.toString(RLM_Parameters.getServerPort())) &&
			tcpPortField.getText().equals(Integer.toString(RLM_Parameters.getTcpPort())) &&
			audioPortField.getText().equals(Integer.toString(RLM_Parameters.getAudioPort())) &&
			videoPortField.getText().equals(Integer.toString(RLM_Parameters.getVideoPort())) &&
			folderField.getText().equals(RLM_Parameters.getReceivedFolder()) &&
			nicToConnect.equals(RLM_Parameters.getNetworkInterfaceToConnect(true)) &&
			lanCheckBox.isSelected() == RLM_Parameters.isLan()
		) {
			return false;
		}
		else {
			return true;
		}
	}
	
	
	private boolean isAutoStartChanged() {
		return ( !autoStartCheckBox.isSelected() == RLMAutostart.isAutoStart() );
	}
	
	private boolean changePortMade() {
		return ( !serverPortField.getText().equals(Integer.toString(RLM_Parameters.getServerPort())) );
	}
	
	private boolean changeTcpPortMade() {
		return ( !tcpPortField.getText().equals(Integer.toString(RLM_Parameters.getTcpPort())) );
	}
	
	private boolean changeAudioPortMade() {
		return ( !audioPortField.getText().equals(Integer.toString(RLM_Parameters.getAudioPort())) );
	}
	
	private boolean changeVideoPortMade() {
		return ( !videoPortField.getText().equals(Integer.toString(RLM_Parameters.getVideoPort())) );
	}
	
	private boolean changeNicToConnectMade() {
		return ( !nicToConnect.equals(RLM_Parameters.getNetworkInterfaceToConnect(true)) );
	}
	
	private JButton getCancelButton() {
		if (cancelButton == null) {
			cancelButton = new JButton("Cancel");
			cancelButton.setToolTipText("Cancel");
			cancelButton.setPreferredSize(new Dimension(80, 25));
			cancelButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					OptionsDialog.this.dispose();
				}
			});
		}
		
		return cancelButton;
	}



	private JTextField getFolderField() {
		if (folderField == null) {
			folderField = new JTextField();
			folderField.setPreferredSize(new Dimension(200,20));
			clientGridBag.setConstraints(folderField, folderFieldConstraint);
			folderField.setText(RLM_Parameters.getReceivedFolder());
		}
		return folderField;
	}



	private JLabel getFolderLabel() {
		if (folderLabel == null) {
			folderLabel = new JLabel("Received Folder:");
			clientGridBag.setConstraints(folderLabel, folderLabelConstraint);
		}
		return folderLabel;
	}



	private JTextField getServerNameField() {
		if (serverNameField == null) {
			serverNameField = new JTextField();
			serverNameField.setPreferredSize(new Dimension(100,20));
			serverGridBag.setConstraints(serverNameField, serverNameFieldConstraint);
			serverNameField.setText(RLM_Parameters.getServerName());
		}
		return serverNameField;
	}



	private JLabel getServerNameLabel() {
		if (serverNameLabel == null) {
			serverNameLabel = new JLabel("Server Name or IP:");
			serverGridBag.setConstraints(serverNameLabel, serverNameLabelConstraint);
		}
		return serverNameLabel;
	}



	private JTextField getServerPortField() {
		if (serverPortField == null) {
			serverPortField = new JTextField();
			serverPortField.setPreferredSize(new Dimension(50,20));
			serverGridBag.setConstraints(serverPortField, serverPortFieldConstraint);
			serverPortField.setText(Integer.toString(RLM_Parameters.getServerPort()));
		}
		return serverPortField;
	}


	private JCheckBox getLanCheckBox() {
		if (lanCheckBox == null) {
			lanCheckBox = new JCheckBox();
			clientGridBag.setConstraints(lanCheckBox, lanCheckBoxConstraint);
			lanCheckBox.setSelected(RLM_Parameters.isLan());
		}
		return lanCheckBox;
	}



	private JLabel getLanLabel() {
		if (lanLabel == null) {
			lanLabel = new JLabel("Is in LAN:");
			clientGridBag.setConstraints(lanLabel, lanLabelConstraint);
		}
		return lanLabel;
	}
	

	private JLabel getServerPortLabel() {
		if (serverPortLabel == null) {
			serverPortLabel = new JLabel("Server Port:");
			serverGridBag.setConstraints(serverPortLabel, serverPortLabelConstraint);
		}
		return serverPortLabel;
	}
	
	
	private JTextField getTcpPortField() {
		if (tcpPortField == null) {
			tcpPortField = new JTextField();
			tcpPortField.setPreferredSize(new Dimension(50,20));
			clientGridBag.setConstraints(tcpPortField, tcpPortFieldConstraint);
			tcpPortField.setText(Integer.toString(RLM_Parameters.getTcpPort()));
		}
		return tcpPortField;
	}



	private JLabel getTcpPortLabel() {
		if (tcpPortLabel == null) {
			tcpPortLabel = new JLabel("TCP Port:");
			clientGridBag.setConstraints(tcpPortLabel, tcpPortLabelConstraint);
		}
		return tcpPortLabel;
	}
	
	private JTextField getAudioPortField() {
		if (audioPortField == null) {
			audioPortField = new JTextField();
			audioPortField.setPreferredSize(new Dimension(50,20));
			clientGridBag.setConstraints(audioPortField, audioPortFieldConstraint);
			audioPortField.setText(Integer.toString(RLM_Parameters.getAudioPort()));
		}
		return audioPortField;
	}


	private JLabel getAudioPortLabel() {
		if (audioPortLabel == null) {
			audioPortLabel = new JLabel("Audio Port:");
			clientGridBag.setConstraints(audioPortLabel, audioPortLabelConstraint);
		}
		return audioPortLabel;
	}
	
	private JTextField getVideoPortField() {
		if (videoPortField == null) {
			videoPortField = new JTextField();
			videoPortField.setPreferredSize(new Dimension(50,20));
			clientGridBag.setConstraints(videoPortField, videoPortFieldConstraint);
			videoPortField.setText(Integer.toString(RLM_Parameters.getVideoPort()));
		}
		return videoPortField;
	}


	private JLabel getVideoPortLabel() {
		if (videoPortLabel == null) {
			videoPortLabel = new JLabel("Video Port:");
			clientGridBag.setConstraints(videoPortLabel, videoPortLabelConstraint);
		}
		return videoPortLabel;
	}
	

	private JButton getBrowseButton() {
		if (browseButton == null) {
			browseButton = new JButton("Browse...");
			browseButton.setPreferredSize(new Dimension(90,20));
			clientGridBag.setConstraints(browseButton, browseButtonConstraint);
			
			browseButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JFileChooser fileChooser = new JFileChooser(RLM_Parameters.getReceivedFolder());
					
					fileChooser.setDialogTitle("Default Received Folder");
					fileChooser.setApproveButtonText("OK");
					fileChooser.setApproveButtonToolTipText("OK");
					
					fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
					
					fileChooser.rescanCurrentDirectory();

					int returnValue = fileChooser.showDialog(OptionsDialog.this, null);

					if (returnValue == JFileChooser.APPROVE_OPTION) {
						folderField.setText(fileChooser.getSelectedFile().getAbsolutePath());
					}
				}
			});
		}
		
		return browseButton;
	}
	
	

	private JLabel getNicLabel() {
		if (nicLabel == null) {
			nicLabel = new JLabel("NIC Adapter:");
			nicPanelGridBag.setConstraints(nicLabel, nicLabelConstraint);
		}
		return nicLabel;
	}
	
	private JLabel getAddressLabel() {
		if (addressLabel == null) {
			addressLabel = new JLabel("Address:");
			nicPanelGridBag.setConstraints(addressLabel, addressLabelConstraint);
		}
		return addressLabel;
	}
	
	private JComboBox getNicComboBox() {
		if (nicComboBox == null) {
			nicComboBox = new JComboBox(NICManagerRLM.getAdapters());
			nicPanelGridBag.setConstraints(nicComboBox, nicComboConstraint);
			nicComboBox.setPreferredSize(new Dimension(330,25));

			NICInfo nicInfo = NICManagerRLM.getNICByAddress(RLM_Parameters.getNetworkInterfaceToConnect(true));
			
			if (nicInfo != null) {
				nicComboBox.setSelectedItem(nicInfo);
			}

			nicComboBox.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setAddresses();
				}
			});
		}
		return nicComboBox;
	}

	
	private JComboBox getAddressComboBox() {
		if (addressComboBox == null) {
			addressComboBox = new JComboBox();
			addressComboBox.setPreferredSize(new Dimension(130,25));
			setAddresses();
			if (RLM_Parameters.getNetworkInterfaceToConnect(true) != null)
				addressComboBox.setSelectedItem(RLM_Parameters.getNetworkInterfaceToConnect(true));
			nicPanelGridBag.setConstraints(addressComboBox, addressComboConstraint);
			
			addressComboBox.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (addressComboBox.getSelectedItem() != null)
						nicToConnect = addressComboBox.getSelectedItem().toString();
				}
			});
		}
		return addressComboBox;
	}


	
	private void setAddresses() {
		addressComboBox.removeAllItems();
		NICInfo temp = (NICInfo)nicComboBox.getSelectedItem();
		if (temp == null)
			return;
		
		if ( temp.getNICName().equals("auto_select") ) {
			isLoopbackAdapter = false;
			loopbackLabel.setForeground(Color.BLACK);
			loopbackLabel.setText("");
			nicToConnect = temp.getNICName();
			addressComboBox.addItem(nicToConnect);
		}
		
		for (InetAddress addr : temp.getNICAddresses()) {
			if (addr.isLoopbackAddress()) {
				loopbackLabel.setForeground(Color.RED);
				loopbackLabel.setText("Loopback !");
				isLoopbackAdapter = true;
			}
			else {
				loopbackLabel.setForeground(Color.BLACK);
				loopbackLabel.setText("");
				isLoopbackAdapter = false;
			}
			addressComboBox.addItem(addr.getHostAddress());
			nicToConnect = addr.getHostAddress();
		}
	}
	
	
	private JPanel getNicPanel() {
		if (nicPanel == null) {
			nicPanel = new JPanel();
			
			nicPanel.setLayout(nicPanelGridBag);
			
			TitledBorder titledBorder = BorderFactory.createTitledBorder(BorderFactory.
					createEtchedBorder(EtchedBorder.RAISED),
					"Network Settings", javax.swing.border.TitledBorder.CENTER,
					javax.swing.border.TitledBorder.DEFAULT_POSITION,
					null, null);
			
			nicPanel.setBorder(titledBorder);
			
			nicPanel.add(getNicLabel());
			nicPanel.add(getNicComboBox());
			nicPanel.add(getAddressLabel());
			nicPanel.add(getAddressComboBox());
			nicPanel.add(getLoopbackLabel());
		}
		
		return nicPanel;
	}
	
	
	private JLabel getLoopbackLabel() {
		nicPanelGridBag.setConstraints(loopbackLabel, loopbackLabelConstraint);
		return loopbackLabel;
	}
	
	
	private JLabel getAutoStartLabel() {
		if (autoStartLabel == null) {
			autoStartLabel = new JLabel("Auto-start:");
			clientGridBag.setConstraints(autoStartLabel, autoStartLabelConstraint);
		}
		return autoStartLabel;
	}
	
	
	private JCheckBox getAutoStartCheckBox() {
		if (autoStartCheckBox == null) {
			autoStartCheckBox = new JCheckBox();
			clientGridBag.setConstraints(autoStartCheckBox, autoStartCheckBoxConstraint);
			autoStartCheckBox.setSelected(RLMAutostart.isAutoStart());
		}
		return autoStartCheckBox;
	}

}
